﻿using Core;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using Dapper;
using System.Data.SqlClient;
using System.Data;
using System.Threading;
using Model;
using System.Collections.Concurrent;
using System.Collections;
using System.Timers;

namespace DAL
{
    public class ReLessionDAL : BaseDAL
    {
        #region 构造函数
        ReResource ReResourceService;
        static object obj = new object(), objles = new object(), objtimer = new object();
        static List<int> tempLess = new List<int>();
        static System.Timers.Timer waitTimer = new System.Timers.Timer();

        public ReLessionDAL()
        {
            ReResourceService = new DAL.ReResource();
            if (!waitTimer.Enabled)
            {
                waitTimer.Elapsed += new ElapsedEventHandler(Second_Elapsed);
                waitTimer.AutoReset = true;
                waitTimer.Interval = 1000 * 10;
                waitTimer.Enabled = true;
            }
        }
        #endregion

        /// <summary>
        /// 下载备课
        /// </summary>
        /// <param name="id">编号</param>
        /// <param name="type">下载方式，0教室编号，1备课编号，2学校编号</param>
        /// <param name="asyncLess"></param>
        public void DownLession(int id = 0, int type = 0, List<AsyncExtID> asyncLess = null)
        {
            #region 下载Action
            Action<int, int> GoDown = (_id, _type) =>
            {
                WebClient wc = new WebClient();
                wc.Encoding = System.Text.Encoding.GetEncoding("utf-8");
                string strLsns = string.Empty;
                try
                {
                    strLsns = wc.DownloadString(ConfigHelper.GetConfigString("RemoteUrl") + "/Ayyfford/GetLession/" + (_id > 0 ? _id.ToString() : _type == 2 ? ConfigHelper.GetConfigString("SchoolID") : ConfigHelper.GetConfigString("RoomID")) + (_type > 0 ? "?type=" + _type : ""));
                }
                catch (Exception ex)
                {
                    Log.errorlog(ex);
                }
                finally
                {
                    wc.Dispose();
                }
                if (!string.IsNullOrWhiteSpace(strLsns))
                {
                    var ldto = JsonConvert.DeserializeObject<List<Model.LessionDto>>(strLsns);

                    if (ldto.Count <= 0) return;

                    #region 数据入库
                    using (var conn = new SqlConnection(connection))
                    {
                        conn.Open();
                        ldto.ForEach(dto =>
                        {
                            IDbTransaction transaction = conn.BeginTransaction();
                            try
                            {
                                #region 备课入库
                                if (dto.lession != null)
                                {
                                    conn.Execute("if not exists ( select ID from ReLession where ID=" + dto.lession.ID + @")  
                                                begin 
                                                    insert into ReLession(ID,SchoolType,MaterialID,ChapterID,ClassPeriod,LessonTitle,LessonMode,PPTResourceID,TaskID,LessonTeacher,TaskStauts,IsShare,ActualTime,InputTime,IsCompleted,UpdateTime) values (@ID,@SchoolType,@MaterialID,@ChapterID,@ClassPeriod,@LessonTitle,@LessonMode,@PPTResourceID,@TaskID,@LessonTeacher,@TaskStauts,@IsShare,@ActualTime,@InputTime,@IsCompleted,@UpdateTime)
                                                end
                                                    else
                                                begin
                                                    update ReLession set SchoolType=@SchoolType,MaterialID=@MaterialID,ChapterID=@ChapterID,ClassPeriod=@ClassPeriod,LessonTitle=@LessonTitle,LessonMode=@LessonMode,PPTResourceID=@PPTResourceID,TaskID=@TaskID,LessonTeacher=@LessonTeacher,TaskStauts=@TaskStauts,IsShare=@IsShare,ActualTime=@ActualTime,InputTime=@InputTime,IsCompleted=@IsCompleted,UpdateTime=@UpdateTime where ID=@ID
                                                end", dto.lession, transaction);
                                }
                                if (dto.lrlri != null)
                                {
                                    conn.Execute("delete ReLessonResourceIndex where LessonID=@LessonID", new { LessonID = dto.lession.ID }, transaction);
                                    dto.lrlri.ForEach(item =>
                                    {
                                        conn.Execute("if not exists ( select LessonID from ReLessonResourceIndex where LessonID=" + item.LessonID + " and StepID=" + item.StepID + @")  
                                                begin 
                                                    insert into ReLessonResourceIndex(LessonID,StepID,StepNo) values (@LessonID,@StepID,@StepNo)
                                                end
                                                    else
                                                begin
                                                    update ReLessonResourceIndex set LessonID=@LessonID,StepID=@StepID,StepNo=@StepNo where LessonID=@LessonID and StepID=@StepID
                                                end", item, transaction);
                                    });
                                }
                                if (dto.lrlrn != null && dto.lrlrn.Count > 0)
                                {
                                    string _stepIds = string.Empty;
                                    dto.lrlrn.ForEach(item =>
                                    {
                                        _stepIds += item.StepID + ",";
                                    });
                                    conn.Execute("delete ReCourseProcessStep where StepID in(select StepID from ReLessonResourceNorm where LessonID=@LessonID and StepID not in(" + _stepIds.Trim(',') + "))", new { LessonID = dto.lession.ID }, transaction);
                                    conn.Execute("delete ReLessonResourceNorm where LessonID=@LessonID", new { LessonID = dto.lession.ID }, transaction);
                                    dto.lrlrn.ForEach(item =>
                                    {
                                        conn.Execute("if not exists ( select LessonID from ReLessonResourceNorm where LessonID=" + item.LessonID + " and  ResourceID=" + item.ResourceID + " and StepID=" + item.StepID + @")  
                                                begin 
                                                    insert into ReLessonResourceNorm(LessonID,StepID,ResourceType,ResourceID,IndexID,Category) values (@LessonID,@StepID,@ResourceType,@ResourceID,@IndexID,@Category)
                                                end
                                                    else
                                                begin
                                                    update ReLessonResourceNorm set LessonID=@LessonID,StepID=@StepID,ResourceType=@ResourceType,ResourceID=@ResourceID,IndexID=@IndexID,Category=@Category where LessonID=@LessonID and StepID=@StepID
                                                end", item, transaction);
                                    });
                                }
                                if (dto.lrcps != null && dto.lrcps.Count > 0)
                                {
                                    string stepIds = string.Empty;
                                    dto.lrcps.ForEach(item =>
                                    {
                                        stepIds += item.StepID + ",";
                                        conn.Execute("if not exists ( select StepID from ReCourseProcessStep where StepID=" + item.StepID + @")  
                                                begin 
                                                    insert into ReCourseProcessStep(StepID,StepName,SubjectCode,CourseMode,StepType,CreatTime) values (@StepID,@StepName,@SubjectCode,@CourseMode,@StepType,@CreatTime)
                                                end
                                                    else
                                                begin
                                                    update ReCourseProcessStep set StepName=@StepName,SubjectCode=@SubjectCode,CourseMode=@CourseMode,StepType=@StepType,CreatTime=@CreatTime where StepID=@StepID
                                                end", item, transaction);
                                    });
                                }
                                #endregion

                                transaction.Commit();

                                lock (objles)
                                {
                                    if (tempLess.Exists(les => les == _id))
                                        tempLess.RemoveAll(les => les == _id);
                                }

                                Log.errorlog(new Exception("备课入库成功！"));
                            }
                            catch (Exception ex)
                            {
                                lock (objles)
                                {
                                    if (!tempLess.Exists(les => les == _id))
                                        tempLess.Add(_id);
                                }
                                transaction.Rollback();
                                Log.errorlog(ex);
                            }
                        });
                        conn.Close();
                    }
                    #endregion

                    #region 根据备课下载资源
                    string _resIds = string.Empty;
                    ldto.ForEach(dto =>
                    {
                        _resIds += (dto.lession.PPTResourceID == null ? "" : dto.lession.PPTResourceID.ToString() + ",");
                        _resIds += (dto.lession.TaskID == null ? "" : dto.lession.TaskID.ToString() + ",");
                        dto.lrlrn.ForEach(lrn =>
                        {
                            _resIds += lrn.ResourceID + ",";
                        });

                        #region 下载资源集合
                        Action<int, int, int> RemoveLession = (__id, __lesid, __type) =>
                        {
                            using (WebClient wcTmp = new WebClient())
                            {
                                wcTmp.Encoding = System.Text.Encoding.GetEncoding("utf-8");

                                string _result = string.Empty;
                                if (type != 1)
                                    _result = wcTmp.DownloadString(string.Format(ConfigHelper.GetConfigString("RemoteUrl") + "/Ayyfford/DelAsyncExtID/{0}?rid={1}&tp={2}&type={3}", (__type == 2 ? ConfigHelper.GetConfigInt("SchoolID") : __id), __lesid, 0, __type));

                                if (_result.ToString().ToLower() == "false")
                                {
                                    Log.errorlog(new Exception("删除已完成同步的课件记录失败！"));
                                }
                            }
                        };

                        var downLessionResourceThread = new Thread(() =>
                        {
                            try
                            {
                                if (!string.IsNullOrWhiteSpace(_resIds))
                                {
                                    WebClient _wc = new WebClient();
                                    _wc.Encoding = System.Text.Encoding.GetEncoding("utf-8");
                                    string strResourceSet = _wc.DownloadString(ConfigHelper.GetConfigString("RemoteUrl") + "/Ayyfford/GetResourceSet/" + _resIds.Trim(','));
                                    _wc.Dispose();
                                    if (!string.IsNullOrWhiteSpace(strResourceSet))
                                    {
                                        var ltr = JsonConvert.DeserializeObject<List<Model.ReResource>>(strResourceSet);
                                        if (ReResourceService.Save(ltr))
                                        {
                                            RemoveLession(id, dto.lession.ID, type);
                                        }
                                    }
                                }
                                else
                                {
                                    RemoveLession(id, dto.lession.ID, type);
                                }
                            }
                            catch (Exception ex)
                            {
                                Log.errorlog(ex);
                            }
                        });
                        downLessionResourceThread.IsBackground = true;
                        downLessionResourceThread.Start();
                        #endregion
                    });
                    #endregion

                    #region 下载备课相关的教材章节
                    ldto.ForEach(dto =>
                    {
                        if (dto.lession.MaterialID != null)
                            new TeachingMaterialDAL().GetTeachingMaterial(dto.lession.MaterialID.Value);

                        if (dto.lession.ChapterID != null)
                            new ChapterDAL().GetChapter(dto.lession.ChapterID.Value);
                    });
                    #endregion
                }
            };
            #endregion

            if (id == 0)
            {
                if (Monitor.TryEnter(obj))
                {
                    try
                    {
                        GoDown(id, type);
                    }
                    finally
                    {
                        Monitor.Exit(obj);
                    }
                }
            }
            else
            {
                new Thread(() =>
                {
                    GoDown(id, type);
                }).Start();
            }
        }


        static void Second_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            if (Monitor.TryEnter(objtimer))
            {
                try
                {
                    if (tempLess.Count > 0)
                    {
                        new DAL.ReLessionDAL().DownLession(tempLess[0], 1);
                    }
                }
                finally
                {
                    Monitor.Exit(objtimer);
                }
            }


        }
    }
}
